/** @file GOTHuart.h This file the API for UART of the GOTH Kick-ass Etherboard.
 * The UART is configured for:
 *	- 9600 baud
 *	- no parity
 *	- 8 data bits
 *	- 1 stop bit
 *	- no flow control
 * Sending is done by polling, receiving data is done on an interrupt driven basis. When characters
 * are received, they are stored in a 32-byte circular software buffer. Use UART_ReadBuffer to read
 * this data. When more than 32 bytes are received, the first bytes will be overwritten.
 *
 * @author Geoffrey Ottoy - Tom Hamelinckx
 * @date 01/07/2011 (last modified)
 *
 * <pre>
 * MODIFICATION HISTORY:
 *
 * Who  Date     Changes
 * ---- -------- ---------------------------------------------------------
 * GO   30/06/11 Created this file.
 * GO   01/07/11 Solved the UART error on reception of more than
 *               RECV_BUFFER_SIZE bytes. (By overwriting previously
 *               received bytes.
 * </pre>
 * 
 */

#ifndef __GOTH_UART_H__
#define __GOTH_UART_H__

#include "uart.h"

#include "p24fj256gb110.h"
#include "GOTHglobal.h"

/// Set baudrate
#define BAUDRATE 9600

/*						FCY			
		BAUDRATE= --------------- -1
				   16 * BAUDRATE
*/
#define BAUDRATEREG FCY/32/BAUDRATE-1

// Check for wrong value of BAUDRATEREG (U2BRG)
#if BAUDRATEREG > 255
#error Cannot set up UART for the requested FCY and BAUDRATE.\
 Correct values in uart.h file.
#endif

// Check for baudrate mistake.
#define BAUDRATE_MISTAKE 1000*(BAUDRATE-FCY/32/(BAUDRATEREG+1))/BAUDRATE
#if (BAUDRATE_MISTAKE > 2)||(BAUDRATE_MISTAKE < -2)
#error UART baudrate mistake is too big for the FCY\
 and BAUDRATE. Correct values in uart.c file.
#endif

/** Set buffersize
 * @warning needs to be a power of 2
 */
#define RECV_BUFFER_SIZE 32
// Mask is calculated automatically
#define RECV_BUFFER_MASK (RECV_BUFFER_SIZE -1)

/// A structure describing the buffer.
typedef struct{
	unsigned char buffer[RECV_BUFFER_SIZE];
	unsigned int out_pointer; // index of the last byte in the buffer
	unsigned int in_pointer; // index of the first byte in the buffer
	unsigned int fill_count; // number of bytes in the buffer
} C_BUFFER;

/** Initialize the UART for operation.
 *
 * @return	nothing
 */
void UART_InitUart(void);

/** Turn on the UART hardware RS-232 driver. Accordingly the green indication LED off the
 * bord will be lit.
 *
 * @return	nothing
 */
void UART_TransceiverOn(void);

/** Turn off the UART hardware RS-232 driver. Accordingly the green indication LED off the
 * bord will be off.
 *
 * @return	nothing
 */
void UART_TransceiverOff(void);

/** Read data from the UART software circular buffer.
 * 
 * @param	buffer	A pointer to the buffer where the bytes will be stored
 * @param	length	Determines how many bytes will be read
 *
 * @return	The number of bytes read. This will be smaller than length, when less bytes were
 *			available
 */
int UART_ReadBuffer(unsigned char * buffer, int length);

/** Sent data over the UART
 * 
 * @param	buffer	A pointer to the buffer that needs to be sent
 * @param	length	Determines how many bytes will be sent
 *
 * @return	The number of bytes sent.
 */
int UART_WriteBuffer(unsigned char * buffer, int length);

#endif //__GOTH_UART_H__
